package net.entelijan.cobean.tree;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang.ClassUtils;

abstract class CobeanTreeUtil {

	private CobeanTreeUtil() {
		super();
	}

	@SuppressWarnings("unchecked")
	public static <T> List<T> getChildren(T value, String childrenMethodName) {
		ArrayList<T> re = new ArrayList<T>();
		try {
			if (childrenMethodName != null) {
				Method childrenMethod = value.getClass().getMethod(
						childrenMethodName);
				if (childrenMethod == null) {
					throw new IllegalStateException(
							"Illegal method to get children '"
									+ childrenMethodName
									+ "'. Method does not exist in "
									+ value.getClass());
				}
				Class<?> returnType = childrenMethod.getReturnType();
				if (ClassUtils.isAssignable(returnType, Iterable.class)) {
					Iterable<T> children = (Iterable<T>) childrenMethod
							.invoke(value);
					if (children != null) {
						for (T child : children) {
							re.add(child);
						}
					}
				} else if (ClassUtils.isAssignable(returnType, Object[].class)) {
					T[] children = (T[]) childrenMethod.invoke(value);
					if (children != null) {
						for (T child : children) {
							re.add(child);
						}
					}
				} else {
					throw new IllegalStateException(
							"Illegal method to get children '"
									+ childrenMethodName
									+ "'. Method does neither return an Iterable nor an Array. "
									+ returnType);
				}
			}
		} catch (Exception e) {
			throw new IllegalStateException("Could not get children from '"
					+ value + "' using '" + childrenMethodName + "' because: "
					+ e.getMessage(), e);
		}
		return re;
	}

}
